package ns

import (
	"GLibHac/fssystem"
	"GLibHac/tools"
	"encoding/binary"
	"fmt"
)

type AccessibleLaunchRequiredVersionValue struct {
	ApplicationId []uint64
}

func NewAccessibleLaunchRequiredVersionValue(reader fssystem.IStorage) (*AccessibleLaunchRequiredVersionValue, error) {
	s, err := reader.ReadUint64s(8)
	if err != nil {
		return nil, err
	}
	return &AccessibleLaunchRequiredVersionValue{s}, nil
}

type CrashScreenshotForDevValue byte

func (c CrashScreenshotForDevValue) String() string {
	switch c {
	case CrashScreenshotForDevValueDeny:
		return "Deny"
	case CrashScreenshotForDevValueAllow:
		return "Allow"
	default:
		return fmt.Sprintf("CrashScreenshotForDevValue(%d)", c)
	}
}

const (
	CrashScreenshotForDevValueDeny = CrashScreenshotForDevValue(iota)
	CrashScreenshotForDevValueAllow
)

type CrashScreenshotForProdValue byte

func (c CrashScreenshotForProdValue) String() string {
	switch c {
	case CrashScreenshotForProdValueDeny:
		return "Deny"
	case CrashScreenshotForProdValueAllow:
		return "Allow"
	default:
		return fmt.Sprintf("CrashScreenshotForProdValue(%d)", c)
	}
}

const (
	CrashScreenshotForProdValueDeny = CrashScreenshotForProdValue(iota)
	CrashScreenshotForProdValueAllow
)

type PlayReportPermissionValue byte

const (
	PlayReportPermissionValueNone = PlayReportPermissionValue(iota)
	PlayReportPermissionValueTargetMarketing
)

func (p PlayReportPermissionValue) String() string {
	switch p {
	case PlayReportPermissionValueNone:
		return "None"
	case PlayReportPermissionValueTargetMarketing:
		return "TargetMarketing"
	default:
		return fmt.Sprintf("PlayReportPermissionValue(%d)", p)
	}
}

type RequiredAddOnContentsSetBinaryDescriptor struct {
	Descriptors []uint16
}

func NewRequiredAddOnContentsSetBinaryDescriptor(reader fssystem.IStorage) (*RequiredAddOnContentsSetBinaryDescriptor, error) {
	s, err := reader.ReadUint16s(32)
	if err != nil {
		return nil, err
	}
	return &RequiredAddOnContentsSetBinaryDescriptor{Descriptors: s}, nil
}

type JitConfigurationFlag uint64

const (
	JitConfigurationFlagNone = JitConfigurationFlag(iota)
	JitConfigurationFlagEnabled
)

func (jcf JitConfigurationFlag) String() string {
	switch jcf {
	case JitConfigurationFlagNone:
		return "None"
	case JitConfigurationFlagEnabled:
		return "Enabled"
	default:
		return fmt.Sprintf("JitConfigurationFlag(%d)", jcf)
	}
}

type ApplicationJitConfiguration struct {
	Flags      JitConfigurationFlag
	MemorySize int64
}

func NewApplicationJitConfiguration(reader fssystem.IStorage) (*ApplicationJitConfiguration, error) {
	bytes, err := reader.ReadBytes(18)
	if err != nil {
		return nil, err
	}
	return &ApplicationJitConfiguration{
		Flags:      JitConfigurationFlag(binary.LittleEndian.Uint64(bytes)),
		MemorySize: int64(binary.BigEndian.Uint64(bytes[9:18])),
	}, nil
}

type ApplicationNeighborDetectionGroupConfiguration struct {
	GroupId uint64
	Key     []byte
}

func NewApplicationNeighborDetectionGroupConfiguration(data []byte) *ApplicationNeighborDetectionGroupConfiguration {
	return &ApplicationNeighborDetectionGroupConfiguration{
		GroupId: binary.LittleEndian.Uint64(data),
		Key:     data[8:24],
	}
}

type ApplicationNeighborDetectionClientConfiguration struct {
	SendGroupConfiguration        *ApplicationNeighborDetectionGroupConfiguration
	ReceivableGroupConfigurations []*ApplicationNeighborDetectionGroupConfiguration
}

func NewApplicationNeighborDetectionClientConfiguration(reader fssystem.IStorage) (*ApplicationNeighborDetectionClientConfiguration, error) {
	bytes, err := reader.ReadBytes(24)
	if err != nil {
		return nil, err
	}
	r := &ApplicationNeighborDetectionClientConfiguration{
		SendGroupConfiguration:        NewApplicationNeighborDetectionGroupConfiguration(bytes),
		ReceivableGroupConfigurations: make([]*ApplicationNeighborDetectionGroupConfiguration, 16),
	}
	for i := 0; i < 16; i++ {
		bytes, err = reader.ReadBytes(24)
		if err != nil {
			return nil, err
		}
		r.ReceivableGroupConfigurations[i] = NewApplicationNeighborDetectionGroupConfiguration(bytes)
	}
	return r, nil
}

type RequiredNetworkServiceLicenseOnLaunchValue byte

func (r RequiredNetworkServiceLicenseOnLaunchValue) String() string {
	switch r {
	case RequiredNetworkServiceLicenseOnLaunchValueNone:
		return "None"
	case RequiredNetworkServiceLicenseOnLaunchValueCommon:
		return "Common"
	default:
		return fmt.Sprintf("RequiredNetworkServiceLicenseOnLaunchValue(%d)", r)
	}
}

const (
	RequiredNetworkServiceLicenseOnLaunchValueNone = RequiredNetworkServiceLicenseOnLaunchValue(iota)
	RequiredNetworkServiceLicenseOnLaunchValueCommon
)

type RepairFlagValue byte

func (r RepairFlagValue) String() string {
	switch r {
	case RepairFlagValueNone:
		return "None"
	case RepairFlagValueSuppressGameCardAccess:
		return "SuppressGameCardAccess"
	default:
		return fmt.Sprintf("RepairFlagValue(%d)", r)
	}
}

const (
	RepairFlagValueNone = RepairFlagValue(iota)
	RepairFlagValueSuppressGameCardAccess
)

type PlayLogQueryCapabilityValue byte

func (c PlayLogQueryCapabilityValue) String() string {
	switch c {
	case PlayLogQueryCapabilityValueNone:
		return "None"
	case PlayLogQueryCapabilityValueWhiteList:
		return "WhiteList"
	case PlayLogQueryCapabilityValueAll:
		return "All"
	default:
		return fmt.Sprintf("PlayLogQueryCapabilityValue(%d)", c)
	}
}

const (
	PlayLogQueryCapabilityValueNone = PlayLogQueryCapabilityValue(iota)
	PlayLogQueryCapabilityValueWhiteList
	PlayLogQueryCapabilityValueAll
)

type StartupUserAccountOptionFlagValue byte

func (s StartupUserAccountOptionFlagValue) String() string {
	switch s {
	case StartupUserAccountOptionFlagValueNone:
		return "None"
	case StartupUserAccountOptionFlagValueIsOptional:
		return "IsOptional"
	default:
		return fmt.Sprintf("StartupUserAccountOptionFlagValue(%d)", s)
	}
}

const (
	StartupUserAccountOptionFlagValueNone = StartupUserAccountOptionFlagValue(iota)
	StartupUserAccountOptionFlagValueIsOptional
)

type HdcpValue byte

func (h HdcpValue) String() string {
	switch h {
	case HdcpValueNone:
		return "None"
	case HdcpValueRequired:
		return "Required"
	default:
		return fmt.Sprintf("HdcpValue(%d)", h)
	}
}

const (
	HdcpValueNone = HdcpValue(iota)
	HdcpValueRequired
)

type CrashReportValue byte

func (c CrashReportValue) String() string {
	switch c {
	case CrashReportValueDeny:
		return "Deny"
	case CrashReportValueAllow:
		return "Allow"
	default:
		return fmt.Sprintf("CrashReportValue(%d)", c)
	}
}

const (
	CrashReportValueDeny = CrashReportValue(iota)
	CrashReportValueAllow
)

type RuntimeParameterDeliveryValue byte

func (r RuntimeParameterDeliveryValue) String() string {
	switch r {
	case RuntimeParameterDeliveryValueAlways:
		return "Always"
	case RuntimeParameterDeliveryValueAlwaysIfUserStateMatched:
		return "AlwaysIfUserStateMatched"
	case RuntimeParameterDeliveryValueOnRestart:
		return "OnRestart"
	default:
		return fmt.Sprintf("RuntimeParameterDeliveryValue(%d)", r)
	}
}

const (
	RuntimeParameterDeliveryValueAlways = RuntimeParameterDeliveryValue(iota)
	RuntimeParameterDeliveryValueAlwaysIfUserStateMatched
	RuntimeParameterDeliveryValueOnRestart
)

type RuntimeAddOnContentInstallValue byte

func (c RuntimeAddOnContentInstallValue) String() string {
	switch c {
	case RuntimeAddOnContentInstallValueDeny:
		return "Deny"
	case RuntimeAddOnContentInstallValueAllowAppend:
		return "AllowAppend"
	case RuntimeAddOnContentInstallValueAllowAppendButDontDownloadWhenUsingNetwork:
		return "AllowAppendButDontDownloadWhenUsingNetwork"
	default:
		return fmt.Sprintf("RuntimeAddOnContentInstallValue(%d)", c)
	}
}

const (
	RuntimeAddOnContentInstallValueDeny = RuntimeAddOnContentInstallValue(iota)
	RuntimeAddOnContentInstallValueAllowAppend
	RuntimeAddOnContentInstallValueAllowAppendButDontDownloadWhenUsingNetwork
)

type LogoHandlingValue byte

func (l LogoHandlingValue) String() string {
	switch l {
	case LogoHandlingValueAuto:
		return "Auto"
	case LogoHandlingValueManual:
		return "Manual"
	default:
		return fmt.Sprintf("LogoHandlingValue(%d)", l)
	}
}

const (
	LogoHandlingValueAuto = LogoHandlingValue(iota)
	LogoHandlingValueManual
)

type LogoTypeValue byte

func (o LogoTypeValue) String() string {
	switch o {
	case LogoTypeValueLicensedByNintendo:
		return "LicensedByNintendo"
	case LogoTypeValueDistributedByNintendo:
		return "DistributedByNintendo"
	case LogoTypeValueNintendo:
		return "Nintendo"
	default:
		return fmt.Sprintf("LogoTypeValue(%d)", o)
	}
}

const (
	LogoTypeValueLicensedByNintendo = LogoTypeValue(iota)
	LogoTypeValueDistributedByNintendo
	LogoTypeValueNintendo
)

type PlayLogPolicyValue byte

func (p PlayLogPolicyValue) String() string {
	switch p {
	case PlayLogPolicyValueOpen:
		return "Open/All"
	case PlayLogPolicyValueLogOnly:
		return "LogOnly"
	case PlayLogPolicyValueNone:
		return "None"
	case PlayLogPolicyValueClosed:
		return "Closed"
	default:
		return fmt.Sprintf("Unknown(%d)", p)
	}
}

const (
	PlayLogPolicyValueOpen = PlayLogPolicyValue(iota)
	PlayLogPolicyValueLogOnly
	PlayLogPolicyValueNone
	PlayLogPolicyValueClosed
	PlayLogPolicyValueAll = PlayLogPolicyValue(0)
)

type DataLossConfirmationValue byte

func (d DataLossConfirmationValue) String() string {
	switch d {
	case DataLossConfirmationValueNone:
		return "None"
	case DataLossConfirmationValueRequired:
		return "Required"
	default:
		return fmt.Sprintf("Unknown(%d)", d)
	}
}

const (
	DataLossConfirmationValueNone = DataLossConfirmationValue(iota)
	DataLossConfirmationValueRequired
)

type VideoCaptureValue byte

func (v VideoCaptureValue) String() string {
	switch v {
	case VideoCaptureValueDisable:
		return "Disable"
	case VideoCaptureValueManual:
		return "Manual"
	case VideoCaptureValueEnable:
		return "Enable"
	default:
		return fmt.Sprintf("Unknown(%d)", v)
	}
}

const (
	VideoCaptureValueDisable = VideoCaptureValue(iota)
	VideoCaptureValueManual
	VideoCaptureValueEnable
)

type ScreenshotValue byte

func (s ScreenshotValue) String() string {
	switch s {
	case ScreenshotValueAllow:
		return "Allow"
	case ScreenshotValueDeny:
		return "Deny"
	default:
		return fmt.Sprintf("Unknown(%d)", s)
	}
}

const (
	ScreenshotValueAllow = ScreenshotValue(iota)
	ScreenshotValueDeny
)

type ParentalControlFlagValue int32

func (p ParentalControlFlagValue) String() string {
	switch p {
	case ParentalControlFlagValueNone:
		return "None"
	case ParentalControlFlagValueFreeCommunication:
		return "FreeCommunication"
	default:
		return fmt.Sprintf("ParentalControlFlagValue(%d)", p)
	}
}

const (
	ParentalControlFlagValueNone = ParentalControlFlagValue(iota)
	ParentalControlFlagValueFreeCommunication
)

type AttributeFlagValue int32

func (a AttributeFlagValue) String() string {
	switch a {
	case AttributeFlagValueNone:
		return "None"
	case AttributeFlagValueDemo:
		return "Demo"
	case AttributeFlagValueRetailInteractiveDisplay:
		return "RetailInteractiveDisplay"
	default:
		return fmt.Sprintf("Unknown(%d)", a)
	}
}

const (
	AttributeFlagValueNone = AttributeFlagValue(iota)
	AttributeFlagValueDemo
	AttributeFlagValueRetailInteractiveDisplay
)

type AddOnContentRegistrationTypeValue byte

type UserAccountSwitchLockValue byte

func (v UserAccountSwitchLockValue) String() string {
	switch v {
	case UserAccountSwitchLockValueDisable:
		return "Disable"
	case UserAccountSwitchLockValueEnable:
		return "Enable"
	default:
		return fmt.Sprintf("UserAccountSwitchLockValue(%d)", v)
	}
}

const (
	UserAccountSwitchLockValueDisable = UserAccountSwitchLockValue(iota)
	UserAccountSwitchLockValueEnable
)

type StartupUserAccountValue byte

func (s StartupUserAccountValue) String() string {
	switch s {
	case StartupUserAccountValueNone:
		return "None"
	case StartupUserAccountValueRequired:
		return "Required"
	case StartupUserAccountValueRequiredWithNetworkServiceAccountAvailable:
		return "RequiredWithNetworkServiceAccountAvailable"
	default:
		return fmt.Sprintf("StartupUserAccountValue(%d)", s)
	}
}

const (
	StartupUserAccountValueNone = StartupUserAccountValue(iota)
	StartupUserAccountValueRequired
	StartupUserAccountValueRequiredWithNetworkServiceAccountAvailable
)

const ApplicationTitleSize = 512 + 256
const ApplicationTitleCount = 16

type ApplicationTitle struct {
	Name      string
	Publisher string
}

func NewApplicationTitle(data []byte) *ApplicationTitle {
	return &ApplicationTitle{
		Name:      tools.Utf8ZToString(data[:512]),
		Publisher: tools.Utf8ZToString(data[512:ApplicationTitleSize]),
	}
}

type ApplicationControlProperty struct {
	Title                                     []*ApplicationTitle
	Isbn                                      []byte
	StartupUserAccount                        StartupUserAccountValue
	UserAccountSwitchLock                     UserAccountSwitchLockValue
	AddOnContentRegistrationType              AddOnContentRegistrationTypeValue
	AttributeFlag                             AttributeFlagValue
	SupportedLanguageFlag                     uint32
	ParentalControlFlag                       ParentalControlFlagValue
	Screenshot                                ScreenshotValue
	VideoCapture                              VideoCaptureValue
	DataLossConfirmation                      DataLossConfirmationValue
	PlayLogPolicy                             PlayLogPolicyValue
	PresenceGroupId                           uint64
	RatingAge                                 []byte
	DisplayVersion                            []byte
	AddOnContentBaseId                        uint64
	SaveDataOwnerId                           uint64
	UserAccountSaveDataSize                   int64
	UserAccountSaveDataJournalSize            int64
	DeviceSaveDataSize                        int64
	DeviceSaveDataJournalSize                 int64
	BcatDeliveryCacheStorageSize              int64
	ApplicationErrorCodeCategory              []byte
	LocalCommunicationId                      []byte
	LogoType                                  LogoTypeValue
	LogoHandling                              LogoHandlingValue
	RuntimeAddOnContentInstall                RuntimeAddOnContentInstallValue
	RuntimeParameterDelivery                  RuntimeParameterDeliveryValue
	Reserved30F4                              []byte
	CrashReport                               CrashReportValue
	Hdcp                                      HdcpValue
	SeedForPseudoDeviceId                     uint64
	BcatPassphrase                            []byte
	StartupUserAccountOption                  StartupUserAccountOptionFlagValue
	ReservedForUserAccountSaveDataOperation   []byte
	UserAccountSaveDataSizeMax                int64
	UserAccountSaveDataJournalSizeMax         int64
	DeviceSaveDataSizeMax                     int64
	DeviceSaveDataJournalSizeMax              int64
	TemporaryStorageSize                      int64
	CacheStorageSize                          int64
	CacheStorageJournalSize                   int64
	CacheStorageDataAndJournalSizeMax         int64
	CacheStorageIndexMax                      uint16
	Reserved318A                              byte
	RuntimeUpgrade                            byte
	SupportingLimitedLicenses                 uint32
	PlayLogQueryableApplicationId             []uint64
	PlayLogQueryCapability                    PlayLogQueryCapabilityValue
	RepairFlag                                RepairFlagValue
	ProgramIndex                              byte
	RequiredNetworkServiceLicenseOnLaunchFlag RequiredNetworkServiceLicenseOnLaunchValue
	Reserved3214                              []byte
	NeighborDetectionClientConfiguration      *ApplicationNeighborDetectionClientConfiguration
	JitConfiguration                          *ApplicationJitConfiguration
	RequiredAddOnContentsSetBinaryDescriptors *RequiredAddOnContentsSetBinaryDescriptor
	PlayReportPermission                      PlayReportPermissionValue
	CrashScreenshotForProd                    CrashScreenshotForProdValue
	CrashScreenshotForDev                     CrashScreenshotForDevValue
	ContentsAvailabilityTransitionPolicy      byte
	Reserved3404                              []byte
	AccessibleLaunchRequiredVersion           *AccessibleLaunchRequiredVersionValue
	Reserved3448                              []byte
}

func NewApplicationControlProperty(reader fssystem.IStorage) (*ApplicationControlProperty, error) {
	r := &ApplicationControlProperty{
		Title: make([]*ApplicationTitle, ApplicationTitleCount),
	}
	for i := 0; i < ApplicationTitleCount; i++ {
		bytes, err := reader.ReadBytes(ApplicationTitleSize)
		if err != nil {
			return nil, err
		}
		r.Title[i] = NewApplicationTitle(bytes)
	}
	var err error
	var byteValue byte
	r.Isbn, err = reader.ReadBytes(37)
	if err != nil {
		return nil, err
	}
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.StartupUserAccount = StartupUserAccountValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.UserAccountSwitchLock = UserAccountSwitchLockValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.AddOnContentRegistrationType = AddOnContentRegistrationTypeValue(byteValue)
	intValue, err := reader.ReadInt()
	if err != nil {
		return nil, err
	}
	r.AttributeFlag = AttributeFlagValue(intValue)
	r.SupportedLanguageFlag, err = reader.ReadUint32()
	if err != nil {
		return nil, err
	}
	intValue, err = reader.ReadInt()
	if err != nil {
		return nil, err
	}
	r.ParentalControlFlag = ParentalControlFlagValue(intValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.Screenshot = ScreenshotValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.VideoCapture = VideoCaptureValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.DataLossConfirmation = DataLossConfirmationValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.PlayLogPolicy = PlayLogPolicyValue(byteValue)
	r.PresenceGroupId, err = reader.ReadUint64()
	if err != nil {
		return nil, err
	}
	r.RatingAge, err = reader.ReadBytes(32)
	if err != nil {
		return nil, err
	}
	r.DisplayVersion, err = reader.ReadBytes(16)
	if err != nil {
		return nil, err
	}
	r.AddOnContentBaseId, err = reader.ReadUint64()
	if err != nil {
		return nil, err
	}
	r.SaveDataOwnerId, err = reader.ReadUint64()
	if err != nil {
		return nil, err
	}
	r.UserAccountSaveDataSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.UserAccountSaveDataJournalSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.DeviceSaveDataSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.DeviceSaveDataJournalSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.BcatDeliveryCacheStorageSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.ApplicationErrorCodeCategory, err = reader.ReadBytes(8)
	if err != nil {
		return nil, err
	}
	r.LocalCommunicationId, err = reader.ReadBytes(8)
	if err != nil {
		return nil, err
	}
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.LogoType = LogoTypeValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.LogoHandling = LogoHandlingValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.RuntimeAddOnContentInstall = RuntimeAddOnContentInstallValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.RuntimeParameterDelivery = RuntimeParameterDeliveryValue(byteValue)
	r.Reserved30F4, err = reader.ReadBytes(2)
	if err != nil {
		return nil, err
	}
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.CrashReport = CrashReportValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.Hdcp = HdcpValue(byteValue)
	r.SeedForPseudoDeviceId, err = reader.ReadUint64()
	if err != nil {
		return nil, err
	}
	r.BcatPassphrase, err = reader.ReadBytes(65)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.StartupUserAccountOption = StartupUserAccountOptionFlagValue(byteValue)
	r.ReservedForUserAccountSaveDataOperation, err = reader.ReadBytes(6)
	if err != nil {
		return nil, err
	}
	r.UserAccountSaveDataSizeMax, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.UserAccountSaveDataJournalSizeMax, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.DeviceSaveDataSizeMax, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.DeviceSaveDataJournalSizeMax, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.TemporaryStorageSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.CacheStorageSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.CacheStorageJournalSize, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.CacheStorageDataAndJournalSizeMax, err = reader.ReadInt64()
	if err != nil {
		return nil, err
	}
	r.CacheStorageIndexMax, err = reader.ReadUint16()
	if err != nil {
		return nil, err
	}
	r.Reserved318A, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.RuntimeUpgrade, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.SupportingLimitedLicenses, err = reader.ReadUint32()
	if err != nil {
		return nil, err
	}
	r.PlayLogQueryableApplicationId, err = reader.ReadUint64s(16)
	if err != nil {
		return nil, err
	}
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.PlayLogQueryCapability = PlayLogQueryCapabilityValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.RepairFlag = RepairFlagValue(byteValue)
	r.ProgramIndex, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.RequiredNetworkServiceLicenseOnLaunchFlag = RequiredNetworkServiceLicenseOnLaunchValue(byteValue)
	r.Reserved3214, err = reader.ReadBytes(4)
	if err != nil {
		return nil, err
	}
	r.NeighborDetectionClientConfiguration, err = NewApplicationNeighborDetectionClientConfiguration(reader)
	if err != nil {
		return nil, err
	}
	r.JitConfiguration, err = NewApplicationJitConfiguration(reader)
	if err != nil {
		return nil, err
	}
	r.RequiredAddOnContentsSetBinaryDescriptors, err = NewRequiredAddOnContentsSetBinaryDescriptor(reader)
	if err != nil {
		return nil, err
	}
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.PlayReportPermission = PlayReportPermissionValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.CrashScreenshotForProd = CrashScreenshotForProdValue(byteValue)
	byteValue, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.CrashScreenshotForDev = CrashScreenshotForDevValue(byteValue)
	r.ContentsAvailabilityTransitionPolicy, err = reader.ReadByte()
	if err != nil {
		return nil, err
	}
	r.Reserved3404, err = reader.ReadBytes(4)
	if err != nil {
		return nil, err
	}
	r.AccessibleLaunchRequiredVersion, err = NewAccessibleLaunchRequiredVersionValue(reader)
	if err != nil {
		return nil, err
	}
	r.Reserved3448, err = reader.ReadBytes(3000)
	if err != nil {
		return nil, err
	}
	return r, nil
}
